#include "static_malloc.h"
#include <stddef.h>
#include <stdint-gcc.h>

void my_mem_init(void);
void mymemset(void* s, uint8_t c, uint32_t count);
void mymemcpy(void *des,void *src,uint32_t n);

//内存管理控制器
struct _m_mallco_dev
{
    void (*init)();             //初始化
    uint8_t* membase;				//内存池 管理SRAMBANK个区域的内存
    uint32_t* memmap; 				//内存管理状态表
    uint8_t  memrdy; 				//内存管理是否就绪
};


uint8_t mem2base[MEM2_MAX_SIZE] __attribute__((section(".exsdram")));
uint32_t mem2mapbase[MEM2_ALLOC_TABLE_SIZE] __attribute__((section(".exsdram")));
 
const uint32_t memtblsize =  MEM2_ALLOC_TABLE_SIZE ;	                //内存表大小
const uint32_t memblksize =  MEM2_BLOCK_SIZE ;					    //内存分块大小
const uint32_t memsize =  MEM2_MAX_SIZE;                             //内存总大小

struct _m_mallco_dev mallco_dev =
{
    my_mem_init,					//内存初始化
    mem2base,			            //内存池
    mem2mapbase,                    //内存管理状态表
    0,  		 					//内存管理未就绪
};

void mymemcpy(void *des,void *src,uint32_t n)  
{  
    uint8_t *xdes=des;
    uint8_t *xsrc=src; 
    while(n--)*xdes++=*xsrc++;  
} 

void mymemset(void* s, uint8_t c, uint32_t count)
{
    uint8_t* xs = s;
    while (count--)* xs++ = c;
}

void my_mem_init(void)
{
    mymemset(mallco_dev.memmap, 0, memtblsize * 4);	    //内存状态表数据清零  
    mallco_dev.memrdy = 1;								//内存管理初始化OK  
}

void *StaticMalloc(size_t xWantedSize)
{
    signed long offset = 0;
    uint32_t nmemb;     
    uint32_t cmemb = 0;
    uint32_t i;
    if (!mallco_dev.memrdy)
    {
        mallco_dev.init(); 
    }
    if (xWantedSize == 0)
    {
        return NULL; 
    }
    nmemb = xWantedSize / memblksize;
    if (xWantedSize % memblksize)
    {
        nmemb++;
    }
    for (offset = memtblsize - 1; offset >= 0; offset--) 
    {
        if (!mallco_dev.memmap[offset])
        {
            cmemb++; 
        }
        else
        {
            cmemb = 0; 
        }
        if (cmemb == nmemb) 
        {
            for (i = 0; i < nmemb; i++) 
            {
                mallco_dev.memmap[offset + i] = nmemb;
            }
            return (offset * memblksize);
        }
    }
    return NULL; 
}

uint8_t StaticFree(uint32_t offset)
{
    int i;
    if (!mallco_dev.memrdy)//未初始化,先执行初始化
    {
        mallco_dev.init();
        return 1;//未初始化  
    }
    if (offset < memsize)//偏移在内存池内. 
    {
        int index = offset / memblksize;			//偏移所在内存块号码  
        int nmemb = mallco_dev.memmap[index];	//内存块数量
        for (i = 0; i < nmemb; i++)  						//内存块清零
        {
            mallco_dev.memmap[index + i] = 0;
        }
        return 0;
    }
    else 
    {
        return 2;//偏移超区了.  
    }
}

